#ifndef _thread_pool_HPP
#define _thread_pool_HPP

#include <vector>
#include <deque>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>

namespace huge {

    class thread_pool{
    public:

        typedef std::function<void()> tp_job;
        typedef std::function<void(int,void*)> tp_job_withPara;
        struct jobStr{
            int jobId;
            void* jobInfo = nullptr;
            tp_job_withPara goToWorkWithPara;   //for function with parameter
            tp_job goToWork;                    //for function without parameter
        };
    private:
        typedef std::deque<jobStr> tp_jobs;
        tp_jobs m_jobs;

        typedef std::vector<std::thread*> tp_worker;
        tp_worker m_workers;
        int m_init_worker_num;

        bool m_is_started;

        std::mutex m_mutex;
        std::condition_variable m_cond;

    public:
        thread_pool(int init_size = 3);
        ~thread_pool();

        void stop();
        void add_job_withPara(const thread_pool::tp_job &job, bool isPriority);
        void add_job_withPara(const tp_job_withPara & job,const int value, void* info, bool isPriority = false);  //thread safe;

    private:
        thread_pool(const thread_pool&);//禁止复制拷贝.
        const thread_pool& operator=(const thread_pool&);

        bool is_started() { return m_is_started; }
        void start();

        void thread_loop();
        jobStr getJob();

    };

}
#endif
